home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Original Shareware 1.1
/
The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso
/
32
/
othello.zip
/
OTH42.BAS
next >
Wrap
BASIC Source File
|
1987-08-23
|
34KB
|
873 lines
REM ** OTHELLO ** VER 4.2 ** DMK ** 08/23/87 **
REM *************************************************************************
DEFINT A-Z: ON ERROR GOTO PROGRAM.ERROR
REM *************************************************************************
REM ** FUNCTIONS **
DEF FNS$(A$)
STATIC A: FNS$="": IF A$="" THEN EXIT DEF
FOR A=LEN(A$) TO 1 STEP -1
IF INSTR(CHR$(0)+" ",MID$(A$,A,1))=0 THEN FNS$=MID$(A$,1,A): A=1
NEXT
END DEF
REM *************************************************************************
REM ** INITIALIZE PROGRAM **
DIM BOARD(64,64),TOKEN$(2),PLAYER$(2),SCORE(2),CLF(6),CLB(6)
DIM DIR(7,1),BAD!(64,1),GP$(10),GP(10,1),CUR.BOARD(64,1),SIDE(8,1)
SCREEN 0,0,0: WIDTH 80: COLOR 7,0: CLS
PRINT " ** OTHELLO **"
PRINT " THE GAME OF OTHELLO"
PRINT
PRINT " WRITTEN AND COMPILED BY DAVID KEIL OF GREENVILLE, SC (803) 295-4971"
PRINT
PRINT " VERSION 4.2"
LOCATE 12,15: PRINT "Would you like sound effects (Y or N)? ";
CALL SCREEN.INPUT((12),(POS(0)),1,"",SN$,"YN"): PRINT SN$;
LOCATE 14,15: PRINT "Do you have a color monitor (Y or N)? ";
CALL SCREEN.INPUT((14),(POS(0)),1,"",A$,"YN"): PRINT A$;
IF A$="Y" THEN RESTORE COLOR.DATA ELSE RESTORE MONO.DATA
FOR A=0 TO 6: READ CLF(A),CLB(A): NEXT
LOCATE 16,15: PRINT "Do you want to use joystick (Y or N)? ";
CALL SCREEN.INPUT((16),(POS(0)),1,"",JS$,"YN"): PRINT JS$;
IF JS$="Y" THEN
LOCATE 18,15: PRINT "Center joystick and push any key.";
WHILE INKEY$="": WEND: CALL MAKE.SOUND((3))
JS2=STICK(0): JS2=STICK(0): JS1=STICK(1)
END IF
RESTORE MOVE.DATA: FOR A=0 TO 7: READ DIR(A,0),DIR(A,1): NEXT
CALL MOUSE((-1),(0),(0),(0)): GOSUB PRINT.INSTR: GOSUB GET.SCORES
RANDOMIZE TIMER
REM *************************************************************************
START:
FOR A=1 TO 64: BOARD(A,0)=0: NEXT: MOVE=1
SCORE(1)=0: SCORE(2)=0: GOSUB DRAW.BOARD: GOSUB DISPLAY.SCORES
CALL PRINT.MSG(("How many players? "),(0))
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,"12"): PLAYERS=VAL(A$)
FOR A=1 TO PLAYERS
CALL PRINT.MSG(("Enter name player"+STR$(A)+": "),A)
GET.NAME:
CALL SCREEN.INPUT((25),(POS(0)),10,PLAYER$(A),PLAYER$(A),"ABCDEFGHIJKLMNOPQRSTUVWXYZ. ")
PLAYER$(A)=FNS$(PLAYER$(A))
IF PLAYER$(A)="" THEN CALL MAKE.SOUND((4)): GOTO GET.NAME
NEXT: IF PLAYERS=1 THEN PLAYER$(2)="COMPUTER"
CALL PRINT.MSG("Enter pattern 1- 2- (1 or 2)?",(0))
LOCATE 24,17: COLOR CLF(1),CLB(1): PRINT TOKEN$(1);
LOCATE 24,21: COLOR CLF(2),CLB(2): PRINT TOKEN$(2);
LOCATE 24,29: COLOR CLF(1),CLB(1): PRINT TOKEN$(1): LOCATE 24,33: PRINT TOKEN$(1);
LOCATE 25,17: COLOR CLF(2),CLB(2): PRINT TOKEN$(2);
LOCATE 25,21: COLOR CLF(1),CLB(1): PRINT TOKEN$(1);
LOCATE 25,29: COLOR CLF(2),CLB(2): PRINT TOKEN$(2);: LOCATE 25,33: PRINT TOKEN$(2);
COLOR CLF(0),CLB(0): LOCATE 25,48
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,"12"): CALL CLEAR.LINE
IF A$="1" THEN RESTORE PATTERN1.DATA ELSE RESTORE PATTERN2.DATA
COLOR CLF(1),CLB(1): LOCATE 3,45: PRINT PLAYER$(1);
COLOR CLF(2),CLB(2): LOCATE 3,60: PRINT PLAYER$(2);
FOR A=1 TO 4: READ B,C,D: CALL DISPLAY.PIECES(B,C,D): NEXT
CALL PRINT.MSG((PLAYER$(1)+" (H)eads or (T)ails? "),(1))
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,"HT")
CALL MAKE.SOUND((5)): CALL WAIT.HERE((.25!))
A=INT(RND(0)*2)+1: IF A=1 THEN B$="It's Heads " ELSE B$="It's Tails "
IF (A=1 AND A$="H") OR (A=2 AND A$="T") THEN CUR.PLYR=1 ELSE CUR.PLYR=2
CALL PRINT.MSG((B$+PLAYER$(CUR.PLYR)+" Goes first."),CUR.PLYR)
CALL WAIT.HERE((3!)): CUR.PLYR=CUR.PLYR XOR 3: MOVE.NUM=1
NEXT.PLAYER:
IF SCORE(1)+SCORE(2)=64 THEN END.FLG=1: GOTO GAME.OVER
CUR.PLYR=CUR.PLYR XOR 3: LOOK.FLG=0: GOSUB FIND.MOVES
IF MOVE.FLG=-1 THEN END.FLG=2: GOTO GAME.OVER
IF MOVE.FLG=0 THEN IF END.FLG THEN GOTO GAME.OVER ELSE END.FLG=1: GOTO NEXT.PLAYER
CALL MAKE.SOUND((2)): END.FLG=0
CALL PRINT.MSG(("It's "+PLAYER$(CUR.PLYR)+"'s turn"),CUR.PLYR)
IF PLAYER$(CUR.PLYR)="COMPUTER" THEN
FOR A=1 TO 64: BAD!(A,0)=1: BAD!(A,1)=1: NEXT: GOSUB COMPUTER.MOVE
CUR.MOVE=CUR.MOVE-1: X=(CUR.MOVE MOD 8)+1: Y=INT(CUR.MOVE/8)
FOR A=1 TO 4:
LOCATE Y*2+2,X*5-3: PRINT TOKEN$(CUR.PLYR);: CALL WAIT.HERE((.25!))
LOCATE Y*2+2,X*5-3: PRINT TOKEN$(0);: CALL WAIT.HERE((.25!))
NEXT: CALL CLEAR.LINE: GOTO MAKE.MOVE
END IF: IF CUR.PLYR=1 THEN M4=&H2200 ELSE M4=&H4400
CALL MOUSE((10),(0),(-1),M4)
X=0: Y=-1: IF CUR.PLYR=1 THEN X1=4: Y1=3 ELSE X1=4: Y1=4
NEXT.PLAYER.1:
CALL GET.MOVEMENT(DIR): IF DIR=8 THEN GOTO MAKE.MOVE
IF DIR>256 THEN
DIR=DIR-256: A=INT(DIR/16)*8+(DIR MOD 16)
IF BOARD(A,0)>=0 THEN CALL MAKE.SOUND((1)): GOTO NEXT.PLAYER.1
IF X>0 AND Y>=0 THEN LOCATE Y*2+2,X*5-2: PRINT " ";
X=DIR MOD 16: Y=INT(DIR/16): GOTO MAKE.MOVE
END IF
IF DIR=9 THEN GOSUB RESTART: GOTO NEXT.PLAYER.1
IF DIR=10 THEN CALL DISPLAY.HELP: GOTO NEXT.PLAYER.1
IF DIR=11 THEN IF MOVE.NUM>3-PLAYERS THEN CALL UNDO.MOVE: GOTO NEXT.PLAYER_
ELSE CALL MAKE.SOUND((1)): GOTO NEXT.PLAYER.1
NEXT.PLAYER.2:
X1=X1+DIR(DIR,0): Y1=Y1+DIR(DIR,1)
NEXT.PLAYER.3:
IF X1=9 THEN X1=1: IF DIR(DIR,0)=1 THEN Y1=Y1+1
IF Y1=8 THEN Y1=0: IF DIR(DIR,1)=1 THEN X1=X1+1: GOTO NEXT.PLAYER.3
NEXT.PLAYER.4:
IF X1=0 THEN X1=8: IF DIR(DIR,0)=-1 THEN Y1=Y1-1
IF Y1=-1 THEN Y1=7: IF DIR(DIR,1)=-1 THEN X1=X1-1: GOTO NEXT.PLAYER.4
A=Y1*8+X1: IF BOARD(A,0)>0 THEN GOTO NEXT.PLAYER.2
IF X>0 AND Y>=0 THEN LOCATE Y*2+2,X*5-2: PRINT " "; ELSE MOVE.FLG=1
X=X1: Y=Y1: LOCATE Y*2+2,X*5-2: PRINT MID$(TOKEN$(CUR.PLYR),2,2);
CALL MAKE.SOUND((3)): GOTO NEXT.PLAYER.1
MAKE.MOVE:
IF X<1 OR Y<0 THEN CALL MAKE.SOUND((1)): GOTO NEXT.PLAYER.1
A=Y*8+X: IF BOARD(A,0)>=0 THEN CALL MAKE.SOUND((1)): GOTO NEXT.PLAYER.1
IF HELP.FLG THEN CALL DISPLAY.HELP
FOR A=1 TO 64
IF BOARD(A,0)<0 THEN BOARD(A,0)=0
BOARD(A,MOVE.NUM)=BOARD(A,0)
NEXT: BOARD(0,MOVE.NUM)=CUR.PLYR: GOSUB UPDATE.MOVE
MOVE.NUM=MOVE.NUM+1: GOTO NEXT.PLAYER
REM *************************************************************************
GAME.OVER:
IF END.FLG=2 THEN MSG$=PLAYER$(CUR.PLYR)+" HAS BEEN SKUNKED. " ELSE MSG$=""
IF SCORE(1)>SCORE(2) THEN MSG$=MSG$+PLAYER$(1)+" HAS WON. ": A=1_
ELSE IF SCORE(1)<SCORE(2) THEN MSG$=MSG$+PLAYER$(2)+" HAS WON. ": A=2_
ELSE MSG$="IT'S A TIE. ":A=0
COLOR CLF(A),CLB(A)
CALL CLEAR.LINE: PRINT MSG$;: CALL MAKE.SOUND((5)): GOSUB UPDATE.SCORES
REM *************************************************************************
REM ** END OF PROGRAM **
END.PROGRAM:
CALL PRINT.MSG(("Play again (Y or N)? "),(0))
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,"YN")
IF A$="Y" THEN GOTO START ELSE CALL MAKE.SOUND((4))
END
PROGRAM.ERROR:
CALL CLEAR.LINE((23),(25)): LOCATE 24,1: PRINT "Program error #";ERR;
CALL MAKE.SOUND((2)): LOCATE 25,1: PRINT "Push any key to end program";
WHILE INKEY$="": WEND: CALL MAKE.SOUND((5))
END
REM *************************************************************************
REM ** START OF SUBROUTINES **
PRINT.INSTR:
IF CLF(3)<>7 THEN COLOR 2,0
CLS: PRINT " O T H E L L O ": PRINT
PRINT " Computer Othello is a game played on an 8 by 8 game board."
PRINT "The object of the game is to `capture' more squares than"
PRINT "your opponent by outflanking his squares with your squares."
PRINT
PRINT " The squares along the wall are valuable because they can"
PRINT "only be `outflanked' in one direction. The corner can not be"
PRINT "recaptured after it has been taken. It is the most important"
PRINT "square to capture.
PRINT " One strategy to use is to avoid any square adjacent to"
PRINT "the wall, while you try to capture wall squares."
PRINT
PRINT
PRINT "To select move:"
PRINT " Use arrow keys or joystick to select desired square."
PRINT " Then press <RETURN>, <SPACE> or joystick button to make move."
PRINT "Other options:"
PRINT " Press <H> (for help) to show all possible moves."
PRINT " Press <U> to undo last move."
PRINT " Press <ESC> to abort game."
LOCATE 25,1: PRINT " Press any key to continue. . . .";
CALL MAKE.SOUND((1)): WHILE INKEY$="": WEND: CALL MAKE.SOUND((3)): RETURN
DRAW.BOARD:
RESTORE BOARD.DATA
READ A$,B$,C$,D$,TOKEN$(0),TOKEN$(1),TOKEN$(2)
IF CLF(3)<>7 THEN TOKEN$(2)=TOKEN$(1)
COLOR CLF(3),CLB(3): CLS: PRINT A$;
FOR A=1 TO 7: PRINT B$;: PRINT C$;: NEXT
PRINT B$;: PRINT D$;
COLOR CLF(1),CLB(1): LOCATE 1,51: PRINT TOKEN$(1);
LOCATE 2,44: PRINT CHR$(200)+STRING$(10,205)+CHR$(188);
COLOR CLF(2),CLB(2): LOCATE 1,66: PRINT TOKEN$(2);
LOCATE 2,59: PRINT CHR$(200)+STRING$(10,205)+CHR$(188);
COLOR CLF(4),0: LOCATE 18,15: PRINT "O T H E L L O";
COLOR 7,0: RETURN
FIND.MOVES:
MOVE.FLG=-1
FOR Y=0 TO 7
FOR X=1 TO 8
A=Y*8+X: Z=0
IF BOARD(A,0)=CUR.PLYR THEN
IF MOVE.FLG=-1 THEN MOVE.FLG=0
ELSEIF BOARD(A,0)=0 THEN
WHILE Z<8: X1=X: Y1=Y: C=0
FIND.MOVE.2:
X1=X1+DIR(Z,0): Y1=Y1+DIR(Z,1): B=Y1*8+X1
IF X1<1 OR X1>8 OR Y1<0 OR Y1>7 THEN GOTO FIND.MOVE.1
IF BOARD(B,0)<=0 THEN GOTO FIND.MOVE.1
IF BOARD(B,0)=(CUR.PLYR XOR 3) THEN C=C+1: GOTO FIND.MOVE.2
IF C>0 THEN BOARD(A,0)=BOARD(A,0)-C: MOVE.FLG=1
FIND.MOVE.1:
Z=Z+1
WEND
END IF
NEXT
NEXT: IF MOVE.FLG<>0 OR LOOK.FLG=1 THEN RETURN
CALL PRINT.MSG((PLAYER$(CUR.PLYR)+" must pass"),CUR.PLYR)
CALL MAKE.SOUND((7)): CALL WAIT.HERE((1!)): RETURN
UPDATE.MOVE:
Z=0: B=10
WHILE Z<8: X1=X: Y1=Y: C=0
UPDATE.MOVE.2:
X1=X1+DIR(Z,0): Y1=Y1+DIR(Z,1): A=Y1*8+X1
IF X1<1 OR X1>8 OR Y1<0 OR Y1>7 THEN GOTO UPDATE.MOVE.1
IF BOARD(A,0)=0 THEN GOTO UPDATE.MOVE.1
IF BOARD(A,0)=(CUR.PLYR XOR 3) THEN C=C+1: GOTO UPDATE.MOVE.2
FOR A=1 TO C
X1=X1-DIR(Z,0): Y1=Y1-DIR(Z,1)
CALL MAKE.SOUND(B): CALL DISPLAY.PIECES(X1,Y1,CUR.PLYR)
B=B+1: CALL WAIT.HERE((.25!))
NEXT
UPDATE.MOVE.1:
Z=Z+1
WEND: CALL MAKE.SOUND((B)): CALL DISPLAY.PIECES(X,Y,CUR.PLYR): RETURN
COMPUTER.MOVE:
CALL CLEAR.LINE: PRINT "Quiet I'm thinking! ";
RESTORE COMPUTER.MOVE.DATA: CUR.MOVE=0: WEIGHT!=0: OTH.PLYR=CUR.PLYR XOR 3
REM ** SELF DEFENSE **
FOR A=1 TO 4: READ FST,STP
FOR B=1 TO 8: SIDE(B,0)=BOARD(FST,0): SIDE(B,1)=FST: FST=FST+STP: NEXT
FOR MOVE=2 TO 7
IF SIDE(MOVE,0)<0 THEN
C=0
FOR B=MOVE+1 TO 8
IF SIDE(B,0)<=0 THEN
C=1: B=8
ELSEIF SIDE(B,0)=OTH.PLYR THEN
C=2: B=8
END IF
NEXT
FOR B=MOVE-1 TO 1 STEP -1
IF SIDE(B,0)<=0 THEN
B=1: IF C=2 THEN C=4
ELSEIF SIDE(B,0)=OTH.PLYR THEN
B=1: IF C=1 THEN C=4
END IF
NEXT: IF C=4 THEN BAD!(SIDE(MOVE,1),0)=.4
ELSEIF SIDE(MOVE,0)=CUR.PLYR AND CUR.MOVE=0 THEN
IF MOVE>2 AND SIDE(MOVE-1,0)=OTH.PLYR THEN
STP=-1: LST=1: FST=8
ELSEIF MOVE<7 AND SIDE(MOVE+1,0)=OTH.PLYR THEN
STP=1: LST=8: FST=1
ELSE
GOTO NEXT.SIDE
END IF
FOR B=MOVE+STP*2 TO LST STEP STP
IF SIDE(B,0)<0 THEN
C=0
IF B<>LST THEN
FOR D=B+STP TO LST STEP STP
IF SIDE(D,0)<=0 THEN C=C OR 1
IF SIDE(D,0)=OTH.PLYR AND (C AND 1)=0 THEN C=C OR 2
IF SIDE(D,0)=CUR.PLYR THEN_
IF D=B+STP*2 AND (C AND 1)=1 THEN C=C OR 8_
ELSE IF (C AND 3)=2 THEN C=C OR 4
NEXT
FOR D=MOVE TO FST STEP -STP
IF SIDE(D,0)<=0 THEN C=C OR 16
IF SIDE(D,0)=OTH.PLYR AND (C AND 16)=0 THEN C=C OR 32
IF SIDE(D,0)=CUR.PLYR AND D=MOVE-STP*2 AND (C AND 16) THEN C=C OR 64
NEXT
END IF
IF C=0 THEN
CUR.MOVE=SIDE(B,1)
ELSEIF C AND 2 THEN
IF (C AND 32)=32 OR (C AND 16)=0 OR (C AND 4)=4 THEN_
CUR.MOVE=SIDE(B,1) ELSE BAD!(SIDE(B,1),0)=.5
ELSEIF C AND 32 THEN
IF (C AND 1)=0 THEN_
CUR.MOVE=SIDE(B,1) ELSE BAD!(SIDE(B,1),0)=.5
ELSEIF C AND 8 THEN
IF (C AND 16)=0 AND (C AND 32)=0 THEN CUR.MOVE=SIDE(B,1)
ELSEIF (C AND 64)=0 THEN
CUR.MOVE=SIDE(B,1)
END IF: IF CUR.MOVE>0 THEN BAD!(CUR.MOVE,0)=1
B=LST
ELSEIF SIDE(B,0)=CUR.PLYR THEN
B=LST
END IF
NEXT
END IF
NEXT.SIDE:
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
NEXT: IF CUR.MOVE>0 AND BAD!(CUR.MOVE,1)>=1 THEN GOTO COMPUTER.MOVE.0
REM ** TRY TO MOVE TO SIDE & SET TRAPS **
FOR A=1 TO 4: READ FST,STP: C=0
FOR B=1 TO 8: SIDE(B,0)=BOARD(FST,0): SIDE(B,1)=FST: FST=FST+STP: NEXT
REM ** CHECK IF OTH.PLYR IS ON THIS SIDE **
FOR B=1 TO 8
IF SIDE(B,0)=CUR.PLYR THEN C=C OR 1_
ELSE IF SIDE(B,0)=OTH.PLYR THEN C=C OR 2
NEXT: IF C<>2 THEN C=1
FOR MOVE=2 TO 7
IF SIDE(MOVE,0)<0 THEN
A!=C
REM ******* CHECK FOR 0█Ox█X00 **
IF MOVE>2 AND MOVE<7 THEN
IF SIDE(MOVE-1,0)=OTH.PLYR AND SIDE(MOVE-2,0)<=0_
AND SIDE(MOVE+1,0)<=0 AND SIDE(MOVE+2,0)=CUR.PLYR THEN
MOVE.FLG=1
IF MOVE>3 THEN IF SIDE(MOVE-3,0)=OTH.PLYR THEN MOVE.FLG=3
FOR B=MOVE+2 TO 8
IF SIDE(B,0)<=0 THEN
IF MOVE.FLG AND 2 THEN MOVE.FLG=0: B=8 ELSE B=8
ELSEIF SIDE(B,0)=OTH.PLYR THEN
MOVE.FLG=0: B=8
END IF
NEXT
IF MOVE.FLG AND 1 THEN
BAD!(SIDE(MOVE,1),0)=1
IF MOVE=3 THEN A!=A!*16 ELSE A!=A!*10
GOTO FOUND.MOVE
END IF
END IF
IF SIDE(MOVE+1,0)=OTH.PLYR AND SIDE(MOVE+2,0)<=0_
AND SIDE(MOVE-1,0)<=0 AND SIDE(MOVE-2,0)=CUR.PLYR THEN
MOVE.FLG=1
IF MOVE<6 THEN IF SIDE(MOVE+3,0)=OTH.PLYR THEN MOVE.FLG=3
FOR B=MOVE-2 TO 1 STEP -1
IF SIDE(B,0)<=0 THEN
IF MOVE.FLG AND 2 THEN MOVE.FLG=0: B=1 ELSE B=1
ELSEIF SIDE(B,0)=OTH.PLYR THEN
MOVE.FLG=0: B=1
END IF
NEXT
IF MOVE.FLG AND 1 THEN
BAD!(SIDE(MOVE,1),0)=1
IF MOVE=6 THEN A!=A!*16 ELSE A!=A!*10
GOTO FOUND.MOVE
END IF
END IF
END IF
REM ******* X█x IS BAD ** OK **
IF MOVE>2 THEN_
IF SIDE(MOVE-1,0)<=0 AND SIDE(MOVE-2,0)=CUR.PLYR THEN_
BAD!(SIDE(MOVE,1),0)=.9
IF MOVE<7 THEN_
IF SIDE(MOVE+1,0)<=0 AND SIDE(MOVE+2,0)=CUR.PLYR THEN_
BAD!(SIDE(MOVE,1),0)=.9
REM ******* CHECK FOR █O██x ** OK **
IF MOVE=5 THEN
IF SIDE(MOVE-1,0)<=0 AND SIDE(MOVE-2,0)<=0_
AND SIDE(MOVE-3,0)=OTH.PLYR AND SIDE(1,0)<=0 THEN
MOVE.FLG=1
FOR B=MOVE+1 TO 8
IF SIDE(B,0)=OTH.PLYR THEN
MOVE.FLG=0: B=8
ELSEIF SIDE(B,0)<=0 THEN
B=8
END IF
NEXT: IF MOVE.FLG THEN A!=A!*10: GOTO FOUND.MOVE
END IF
ELSEIF MOVE=4 THEN
IF SIDE(MOVE+1,0)<=0 AND SIDE(MOVE+2,0)<=0_
AND SIDE(MOVE+3,0)=OTH.PLYR AND SIDE(8,0)<=0 THEN
MOVE.FLG=1
FOR B=MOVE-1 TO 1 STEP -1
IF SIDE(B,0)=OTH.PLYR THEN
MOVE.FLG=0: B=1
ELSEIF SIDE(B,0)<=0 THEN
B=1
END IF
NEXT: IF MOVE.FLG THEN A!=A!*10: GOTO FOUND.MOVE
END IF
END IF
REM ******* CHECK FOR Ox? OR ?xO **
IF SIDE(MOVE-1,0)=OTH.PLYR THEN
MOVE.FLG=0
FOR B=MOVE+1 TO 8
IF SIDE(B,0)<=0 THEN
B=8: IF MOVE.FLG=0 OR MOVE.FLG=3 THEN MOVE.FLG=2
ELSEIF SIDE(B,0)=OTH.PLYR THEN
IF MOVE.FLG=3 THEN MOVE.FLG=1: B=8 ELSE MOVE.FLG=1
ELSEIF SIDE(B,0)=CUR.PLYR AND MOVE.FLG=1 THEN
MOVE.FLG=3
END IF
NEXT
IF MOVE.FLG=0 THEN A!=A!*4
IF MOVE.FLG=1 THEN A!=A!*5
IF MOVE.FLG=2 THEN BAD!(SIDE(MOVE,1),0)=.6
IF MOVE.FLG=3 THEN A!=A!*8
GOTO FOUND.MOVE
ELSEIF SIDE(MOVE+1,0)=OTH.PLYR THEN
MOVE.FLG=0
FOR B=MOVE-1 TO 1 STEP -1
IF SIDE(B,0)<=0 THEN
B=1: IF MOVE.FLG=0 OR MOVE.FLG=3 THEN MOVE.FLG=2
ELSEIF SIDE(B,0)=OTH.PLYR THEN
IF MOVE.FLG=3 THEN MOVE.FLG=1: B=1 ELSE MOVE.FLG=1
ELSEIF SIDE(B,0)=CUR.PLYR AND MOVE.FLG=1 THEN
MOVE.FLG=3
END IF
NEXT
IF MOVE.FLG=0 THEN A!=A!*4
IF MOVE.FLG=1 THEN A!=A!*5
IF MOVE.FLG=2 THEN BAD!(SIDE(MOVE,1),0)=.6
IF MOVE.FLG=3 THEN A!=A!*8
GOTO FOUND.MOVE
END IF
REM ******* AVOID █x██O **
IF MOVE=2 THEN
IF SIDE(1,0)<=0 AND SIDE(MOVE+1,0)<=0_
AND SIDE(MOVE+2,0)<=0 AND SIDE(MOVE+3,0)<>CUR.PLYR THEN_
BAD!(SIDE(MOVE,1),0)=.1: GOTO FOUND.MOVE
ELSEIF MOVE=7 THEN
IF SIDE(8,0)<=0 AND SIDE(MOVE-1,0)<=0_
AND SIDE(MOVE-2,0)<=0 AND SIDE(MOVE-3,0)<>CUR.PLYR THEN_
BAD!(SIDE(MOVE,1),0)=.1: GOTO FOUND.MOVE
END IF
REM ******* CHECK FOR ??x??x?? ** OK **
IF MOVE=3 OR MOVE=6 THEN
A!=A!*4
REM ******* ALL OTHERS ** OK **
ELSEIF MOVE=2 OR MOVE=7 THEN
IF C>1 THEN A!=A!*2 ELSE A!=.25
ELSE
A!=A!*3
END IF
FOUND.MOVE:
NEW.MOVE=SIDE(MOVE,1)
IF ((MOVE=2 AND SIDE(1,0)=OTH.PLYR) OR (MOVE=7 AND SIDE(8,0)=OTH.PLYR))_
AND BAD!(NEW.MOVE,0)>=1 AND BAD!(NEW.MOVE,1)>=1 THEN A!=A!*2
REM ** CHOOSE BETTER MOVE **
A!=ABS(BOARD(NEW.MOVE,0))*BAD!(NEW.MOVE,1)*A!
IF CUR.MOVE=0 OR BAD!(NEW.MOVE,1)>BAD!(CUR.MOVE,1) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,1)=BAD!(CUR.MOVE,1) THEN
IF BAD!(NEW.MOVE,0)>BAD!(CUR.MOVE,0) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,0)=BAD!(CUR.MOVE,0) THEN
IF A!>WEIGHT! OR (A!=WEIGHT! AND INT(RND(0)*3)+1=2) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
END IF
END IF
END IF
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
NEXT
IF CUR.MOVE>0 AND BAD!(CUR.MOVE,0)>=1 AND BAD!(CUR.MOVE,1)>=1 THEN GOTO COMPUTER.MOVE.0
REM ** CHECK FOUR CORNERS **
FOR A=1 TO 4: READ NEW.MOVE
IF BOARD(NEW.MOVE,0)<0 AND (CUR.MOVE=0 OR BAD!(CUR.MOVE,0)<1) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=1
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
REM ** CHECK INNER SQUARE **
FOR A=1 TO 12: READ NEW.MOVE
IF BOARD(NEW.MOVE,0)<0 THEN
REM ** CHOOSE BETTER MOVE **
IF A<5 THEN A!=3 ELSE A!=2.5
A!=ABS(BOARD(NEW.MOVE,0))*BAD!(NEW.MOVE,1)*A!
IF CUR.MOVE=0 OR BAD!(NEW.MOVE,1)>BAD!(CUR.MOVE,1) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,1)=BAD!(CUR.MOVE,1) THEN
IF BAD!(NEW.MOVE,0)>BAD!(CUR.MOVE,0) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,0)=BAD!(CUR.MOVE,0) THEN
IF A!>WEIGHT! OR (A!=WEIGHT! AND INT(RND(0)*3)+1=2) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
END IF
END IF
END IF
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
IF CUR.MOVE>0 AND BAD!(CUR.MOVE,0)>=1 AND BAD!(CUR.MOVE,1)>=1 THEN GOTO COMPUTER.MOVE.0
REM ** CHECK OUTER SQUARE **
FOR A=1 TO 4: READ FST,STP: C=0: A!=1
FOR B=1 TO 8
IF BOARD(FST,0)=CUR.PLYR THEN C=C OR 2
IF BOARD(FST,0)=OTH.PLYR THEN C=C OR 1
FST=FST+STP
NEXT: READ NEW.MOVE,STP
FOR B=1 TO 4
IF C=0 THEN A!=.25 ELSE IF C=1 THEN A!=.5 ELSE A!=C
IF BOARD(NEW.MOVE,0)<0 THEN
REM ** CHOOSE BETTER MOVE **
A!=ABS(BOARD(NEW.MOVE,0))*BAD!(NEW.MOVE,1)*A!
IF CUR.MOVE=0 OR BAD!(NEW.MOVE,1)>BAD!(CUR.MOVE,1) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,1)=BAD!(CUR.MOVE,1) THEN
IF BAD!(NEW.MOVE,0)>BAD!(CUR.MOVE,0) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,0)=BAD!(CUR.MOVE,0) THEN
IF A!>WEIGHT! OR (A!=WEIGHT! AND INT(RND(0)*3)+1=2) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
END IF
END IF
END IF: NEW.MOVE=NEW.MOVE+STP
NEXT
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
IF CUR.MOVE>0 AND BAD!(CUR.MOVE,0)>=1 AND BAD!(CUR.MOVE,1)>=1 THEN GOTO COMPUTER.MOVE.0
REM ** CHECK FOUR CORNERS AND TAKE 10 15 50 55 IF TAKEN **
FOR A=1 TO 4: READ B,NEW.MOVE
IF BOARD(B,0)>0 THEN
IF BOARD(NEW.MOVE,0)<0 THEN
REM ** CHOOSE BETTER MOVE **
A!=ABS(BOARD(NEW.MOVE,0))*BAD!(NEW.MOVE,1)
IF CUR.MOVE=0 OR BAD!(NEW.MOVE,1)>BAD!(CUR.MOVE,1) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,1)=BAD!(CUR.MOVE,1) THEN
IF BAD!(NEW.MOVE,0)>BAD!(CUR.MOVE,0) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,0)=BAD!(CUR.MOVE,0) THEN
IF A!>WEIGHT! OR (A!=WEIGHT! AND INT(RND(0)*3)+1=2) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
END IF
END IF
END IF
END IF
NEXT: CALL MAKE.SOUND((8)): PRINT ".";
IF CUR.MOVE>0 AND BAD!(CUR.MOVE,0)>=1 AND BAD!(CUR.MOVE,1)>=1 THEN GOTO COMPUTER.MOVE.0
REM ** CHECK 10 15 50 55 **
FOR A=1 TO 4: READ NEW.MOVE: BAD!(NEW.MOVE,0)=.3
IF BOARD(NEW.MOVE,0)<0 THEN
REM ** CHOOSE BETTER MOVE **
A!=ABS(BOARD(NEW.MOVE,0))*BAD!(NEW.MOVE,1)
IF CUR.MOVE=0 OR BAD!(NEW.MOVE,1)>BAD!(CUR.MOVE,1) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,1)=BAD!(CUR.MOVE,1) THEN
IF BAD!(NEW.MOVE,0)>BAD!(CUR.MOVE,0) THEN
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
ELSEIF BAD!(NEW.MOVE,0)=BAD!(CUR.MOVE,0) THEN
IF A!>WEIGHT! OR (A!=WEIGHT! AND INT(RND(0)*3)+1=2) THEN_
CUR.MOVE=NEW.MOVE: WEIGHT!=A!
END IF
END IF
END IF
NEXT
COMPUTER.MOVE.0:
IF BAD!(CUR.MOVE,1)<1 THEN RETURN ELSE LOOK.FLG=0
RESTORE COMPUTER.MOVE.DATA.1
FOR A=1 TO 4: READ B,C,D,E
IF BOARD(B,0)<=0 THEN_
IF BOARD(C,0)>0 OR BOARD(D,0)>0 OR BOARD(E,0)>0_
OR CUR.MOVE=C OR CUR.MOVE=D OR CUR.MOVE=E THEN LOOK.FLG=1
NEXT: IF LOOK.FLG=0 THEN RETURN
FOR A=1 TO 64
CUR.BOARD(A,0)=BOARD(A,0)
IF BOARD(A,0)<0 THEN BOARD(A,0)=0
NEXT: CUR.PLYR=CUR.PLYR XOR 3: GOSUB FIND.MOVES
FOR A=1 TO 64
CUR.BOARD(A,1)=BOARD(A,0)
IF CUR.BOARD(A,0)>=0 THEN BOARD(A,0)=CUR.BOARD(A,0) ELSE BOARD(A,0)=0
NEXT: CUR.PLYR=CUR.PLYR XOR 3
X=((CUR.MOVE-1) MOD 8)+1: Y=INT((CUR.MOVE-1)/8): Z=0
WHILE Z<8: X1=X: Y1=Y: C=0
COMPUTER.MOVE.2:
X1=X1+DIR(Z,0): Y1=Y1+DIR(Z,1): A=Y1*8+X1
IF X1<1 OR X1>8 OR Y1<0 OR Y1>7 THEN GOTO COMPUTER.MOVE.1
IF BOARD(A,0)=0 THEN GOTO COMPUTER.MOVE.1
IF BOARD(A,0)=(CUR.PLYR XOR 3) THEN C=C+1: GOTO COMPUTER.MOVE.2
FOR A=1 TO C
X1=X1-DIR(Z,0): Y1=Y1-DIR(Z,1): BOARD(X1+Y1*8,0)=CUR.PLYR
NEXT
COMPUTER.MOVE.1:
Z=Z+1
WEND: BOARD(X+Y*8,0)=CUR.PLYR: CUR.PLYR=CUR.PLYR XOR 3: GOSUB FIND.MOVES
IF MOVE.FLG<1 THEN GOTO COMPUTER.RETURN
FOR A=1 TO 4: READ NEW.MOVE
IF CUR.BOARD(NEW.MOVE,0)<0 AND BOARD(NEW.MOVE,0)<0 THEN
CUR.MOVE=NEW.MOVE
ELSEIF BOARD(NEW.MOVE,0)<0 AND CUR.BOARD(NEW.MOVE,1)=0 THEN
BAD!(CUR.MOVE,1)=.001: CUR.MOVE=0
END IF
NEXT
COMPUTER.RETURN:
FOR A=1 TO 64: BOARD(A,0)=CUR.BOARD(A,0): NEXT: CUR.PLYR=CUR.PLYR XOR 3
IF CUR.MOVE=0 THEN GOTO COMPUTER.MOVE ELSE RETURN
RESTART:
CALL PRINT.MSG(("Abort game (Y or N)? "),(0))
CALL SCREEN.INPUT((25),(POS(0)),1,"N",A$,"YN")
IF A$="Y" THEN RETURN GAME.OVER
CALL PRINT.MSG(("It's "+PLAYER$(CUR.PLYR)+"'s turn"),CUR.PLYR): RETURN
DISPLAY.SCORES:
LOCATE 5,44: COLOR CLF(4),CLB(4): PRINT" Greatest Players Ever "
COLOR CLF(5),CLB(5): LOCATE ,44
PRINT " Name Wins Losses": LOCATE ,44
PRINT "-------------- ---- ----"
FOR B=1 TO 9
LOCATE ,44: PRINT STR$(B)+"."+GP$(B);TAB(61);USING"### ###";GP(B,0);GP(B,1)
NEXT
LOCATE ,44: PRINT "10."+GP$(10);TAB(61);USING"### ###";GP(10,0);GP(10,1)
COLOR 7,0: RETURN
UPDATE.SCORES:
IF A=0 OR END.FLG=0 THEN RETURN
CUR.PLYR=A: FOR A=1 TO 10: IF GP$(A)<>"" THEN NEXT: A=10 ELSE A=A-1
GOSUB UPDATE.SCORES.1: GP$(B)=PLAYER$(CUR.PLYR): GP(B,0)=GP(B,0)+1
CUR.PLYR=CUR.PLYR XOR 3
GOSUB UPDATE.SCORES.1: GP$(B)=PLAYER$(CUR.PLYR): GP(B,1)=GP(B,1)+1
FOR B=1 TO A
FOR C=B TO A
IF GP(C,0)/(GP(C,1)+.1)>GP(B,0)/(GP(B,1)+.1) THEN_
SWAP GP$(B),GP$(C): SWAP GP(B,0),GP(C,0): SWAP GP(B,1),GP(C,1)
NEXT
NEXT: GOSUB PUT.SCORES: GOSUB DISPLAY.SCORES: RETURN
UPDATE.SCORES.1:
FOR B=1 TO A: IF GP$(B)=PLAYER$(CUR.PLYR) THEN RETURN
NEXT: COLOR CLF(CUR.PLYR),CLB(CUR.PLYR)
CALL CLEAR.LINE: PRINT PLAYER$(CUR.PLYR)+"'s name not found.";
CALL PRINT.MSG("Enter number of player or <RETURN> if new player. ",CUR.PLYR)
CALL SCREEN.INPUT((25),(POS(0)),2,"",A$,"1234567890")
IF A$<>"" THEN IF VAL(A$)>A OR VAL(A$)<1 THEN GOTO UPDATE.SCORES.1_
ELSE B=VAL(A$): CALL CLEAR.LINE: RETURN
IF A<10 THEN A=A+1: B=A: CALL CLEAR.LINE: RETURN
UPDATE.SCORES.2:
CALL CLEAR.LINE: PRINT "Top players list is full."
CALL PRINT.MSG("Enter number of player to delete or <RETURN> to not list new player. ",CUR.PLYR)
CALL SCREEN.INPUT((25),(POS(0)),2,"",A$,"1234567890")
IF A$<>"" THEN IF VAL(A$)>A OR VAL(A$)<1 THEN GOTO UPDATE.SCORES.2_
ELSE B=VAL(A$) ELSE B=0
CALL CLEAR.LINE: RETURN
GET.SCORES:
ON ERROR GOTO GETERR
OPEN"R",1,"OTHELLO.TOP",512: FIELD 1,512 AS A$: GET 1,1
FOR A=1 TO 512: MID$(A$,A,1)=CHR$(ASC(MID$(A$,A,1)) XOR 255): NEXT
IF MID$(A$,1,3)="TOP" THEN
FOR A=1 TO 10
GP$(A)=FNS$(MID$(A$,A*14-10,10)): GP(A,0)=CVI(MID$(A$,A*14,2))
GP(A,1)=CVI(MID$(A$,A*14+2,2))
NEXT
ELSE
FOR A=1 TO 10: GP$(A)="": GP(A,0)=0: GP(A,1)=0: NEXT
END IF: CLOSE
GETRET:
ON ERROR GOTO PROGRAM.ERROR: RETURN
GETERR:
LOCATE 24,1: PRINT "PROBLEMS EXIST PREVENTING THE LOADING OF THE HIGH SCORES.";
LOCATE 25,1: PRINT "CORRECT PROBLEM AND PRESS 'ENTER' OR PRESS 'A' TO ABORT LOAD. ";
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,("A"+CHR$(13))): CALL CLEAR.LINE
LOCATE 25,1: PRINT SPACE$(79);: LOCATE 25,1
IF A$="" THEN RESUME GET.SCORES ELSE RESUME GETRET
PUT.SCORES:
ON ERROR GOTO PUTERR
OPEN"R",1,"OTHELLO.TOP",512: FIELD 1,512 AS A$: B$="TOP"
FOR A=1 TO 10
B$=B$+GP$(A)+SPACE$(10-LEN(GP$(A)))+MKI$(GP(A,0))+MKI$(GP(A,1))
NEXT: B$=B$+SPACE$(512-LEN(B$))
FOR A=1 TO 255: MID$(B$,A,1)=CHR$(ASC(MID$(B$,A,1)) XOR 255): NEXT
LSET A$=B$: PUT 1,1: CLOSE
PUTRET:
ON ERROR GOTO PROGRAM.ERROR: RETURN
PUTERR:
LOCATE 24,1: PRINT "PROBLEMS EXIST PREVENTING THE SAVING OF THE HIGH SCORES.";
LOCATE 25,1: PRINT "CORRECT PROBLEM AND PRESS 'ENTER' OR PRESS 'A' TO ABORT SAVE. ";
CALL SCREEN.INPUT((25),(POS(0)),1,"",A$,("A"+CHR$(13))): CALL CLEAR.LINE
LOCATE 25,1: PRINT SPACE$(79);: LOCATE 25,1
IF A$="" THEN RESUME PUT.SCORES ELSE RESUME PUTRET
REM *************************************************************************
REM ** DATA STATEMENTS **
BOARD.DATA:
DATA "╔════╦════╦════╦════╦════╦════╦════╦════╗"
DATA "║ ║ ║ ║ ║ ║ ║ ║ ║"
DATA "╠════╬════╬════╬════╬════╬════╬════╬════╣"
DATA "╚════╩════╩════╩════╩════╩════╩════╩════╝"
DATA " ","▐██▌","▐▒▒▌"
COLOR.DATA:
DATA 7,0,2,0,4,0,6,0,14,4,10,1,0,0
MONO.DATA:
DATA 7,0,7,0,7,0,7,0,15,7,0,7,0,0
MOVE.DATA:
DATA -1,-1,0,-1,1,-1,1,0,1,1,0,1,-1,1,-1,0
PATTERN1.DATA:
DATA 4,3,1,5,3,2,4,4,2,5,4,1
PATTERN2.DATA:
DATA 4,3,1,5,3,1,4,4,2,5,4,2
COMPUTER.MOVE.DATA:
REM ** SELF DEFENSE **
DATA 1,1, 8,8, 57,1, 1,8
REM ** TRY TO MOVE TO SIDE & SET TRAPS **
DATA 1,1, 8,8, 57,1, 1,8
REM ** CHECK FOUR CORNERS **
DATA 1,8,57,64
REM ** CHECK INNER SQUARE **
DATA 19,22,43,46
DATA 20,21,30,38,45,44,35,27
REM ** CHECK OUTER SQUARE **
DATA 1,1,11,1, 8,8,23,8, 57,1,51,1, 1,8,18,8
REM ** CHECK FOUR CORNERS AND TAKE 10 15 50 55 IF TAKEN **
DATA 1,10, 8,15, 64,55, 57,50
REM ** CHECK 10 15 50 55 **
DATA 10,15,55,50
COMPUTER.MOVE.DATA.1:
DATA 1,2,9,10, 8,7,16,15, 57,49,58,50, 64,56,63,55
DATA 1,8,57,64
REM *************************************************************************
REM ** START OF SUBPROGRAMS **
'Prompt screen for input
' ROW% = Prompt row, COL% = Prompt column
' MAX% = Max # chars to input
' CUR$ = Current value of field being prompted, field not altered.
' INP$ = Return value
' VALID$ = Valid chars during input (see OPT 4)
SUB SCREEN.INPUT(ROW,COL,MAX,CUR$,INP$,VALID$) STATIC
INPSTART:
CALL MAKE.SOUND((1)): CPS=1: STRFLG=1: INP$=CUR$
IF LEN(INP$)>MAX THEN INP$=LEFT$(INP$,MAX) ELSE INP$=INP$
INPCLEAR:
INSFLG=0: SIZ=LEN(INP$): LOCATE ROW,COL,1
PRINT INP$+STRING$(MAX-SIZ,95);: LOCATE ,COL+CPS-1
INPGET:
IP$=INKEY$: ON LEN(IP$)+1 GOTO INPGET,INPCHR
IP=ASC(RIGHT$(IP$,1)): GOTO INPFUN
INPCHR:
IP=ASC(IP$): IF IP>96 AND IP<123 THEN IP=IP AND 223: IP$=CHR$(IP)
IF INSTR(VALID$,IP$)=0 THEN GOTO INPCTL
INPDIS:
IF CPS>MAX THEN GOTO INPERR ELSE CPS=CPS+1
IF CPS-1>SIZ THEN
SIZ=SIZ+1: INP$=INP$+IP$: PRINT IP$;
ELSEIF INSFLG=1 THEN
SIZ=SIZ+1: INP$=LEFT$(INP$,CPS-2)+IP$+MID$(INP$,CPS-1)
IF SIZ>MAX THEN INP$=LEFT$(INP$,MAX): SIZ=MAX
PRINT MID$(INP$,CPS-1);: LOCATE ,COL+CPS-1
ELSE
INP$=LEFT$(INP$,CPS-2)+IP$+MID$(INP$,CPS): PRINT IP$;
END IF
IF MAX=1 THEN IP=13: GOTO INPFUN
IF STRFLG THEN STRFLG=0: INP$=IP$: CPS=2: CALL MAKE.SOUND((3)): GOTO INPCLEAR_
ELSE GOTO INPOK
INPCTL:
IF IP>=32 THEN GOTO INPERR
INPFUN:
IF IP<>13 THEN STRFLG=0
ON INSTR(CHR$(8)+CHR$(13)+CHR$(27)+"GKMORS",CHR$(IP))_
GOTO INPBS,INPRET,INPSTART,INPBG,INPLC,INPRC,INPED,INPINS,INPDL
INPERR:
CALL MAKE.SOUND((1)): GOTO INPGET
INPOK:
CALL MAKE.SOUND((3)): GOTO INPGET
INPBS:
IF CPS=1 THEN GOTO INPERR ELSE CPS=CPS-1: SIZ=SIZ-1
IF CPS>SIZ THEN INP$=LEFT$(INP$,SIZ)_
ELSE INP$=LEFT$(INP$,CPS-1)+MID$(INP$,CPS+1)
LOCATE ,POS(0)-1: PRINT MID$(INP$,CPS)+STRING$(MAX-SIZ,95);
LOCATE ,COL+CPS-1: GOTO INPOK
INPBG:
CPS=1: LOCATE ,COL: GOTO INPOK
INPLC:
IF CPS>1 THEN CPS=CPS-1: PRINT CHR$(29);: GOTO INPOK ELSE GOTO INPERR
INPRC:
IF CPS<SIZ+1 THEN CPS=CPS+1: PRINT CHR$(28);: GOTO INPOK ELSE GOTO INPERR
INPED:
CPS=SIZ+1: LOCATE ,COL+CPS-1: GOTO INPOK
INPINS:
INSFLG=INSFLG XOR 1: GOTO INPOK
INPDL:
IF SIZ>=CPS THEN PRINT CHR$(28);: CPS=CPS+1: GOTO INPBS ELSE GOTO INPERR
INPRET:
IF MAX=1 AND INP$="" AND INSTR(VALID$,CHR$(13))=0 THEN GOTO INPGET
LOCATE ROW,COL,0: PRINT SPACE$(MAX);: LOCATE ROW,COL
END SUB
SUB MAKE.SOUND(X) STATIC
SHARED SN$: IF X=8 THEN CALL WAIT.HERE((.2!))
IF SN$<>"Y" THEN EXIT SUB
IF X=1 THEN
PLAY "L64T200N70"
ELSEIF X=2 THEN
PLAY "T150MFMLL64O5CC#DD#EFF#GG#AA#B"
ELSEIF X=3 THEN
PLAY "L64T200N46"
ELSEIF X=4 THEN
BEEP
ELSEIF X=5 THEN
PLAY "T200MFL32O5CC#DD#EFF#GG#AA#AG#GF#FED#DC#C"
ELSEIF X=6 THEN
PLAY "L64T255N70"
ELSEIF X=7 THEN
FOR A=1 TO 7: SOUND 100,1: SOUND 120,1: NEXT
ELSEIF X=8 THEN
PLAY "L64T200N60"
ELSEIF X>=10 THEN
PLAY "T120L16MFN"+MID$(" 37394142444648495153545658606163656668707273757778808284",(X-9)*2,2)
END IF
END SUB
SUB DISPLAY.PIECES(X,Y,PLAYER) STATIC
SHARED BOARD(),TOKEN$(),SCORE(),CLF(),CLB(): A=BOARD(Y*8+X,0)
IF A<>PLAYER THEN SCORE(PLAYER)=SCORE(PLAYER)+1: BOARD(Y*8+X,0)=PLAYER:_
IF A<>0 THEN SCORE(PLAYER XOR 3)=SCORE(PLAYER XOR 3)-1
COLOR CLF(PLAYER),CLB(PLAYER): LOCATE Y*2+2,X*5-3: PRINT TOKEN$(PLAYER);
COLOR CLF(1),CLB(1): LOCATE 1,46: PRINT USING "##";SCORE(1);: PRINT " -";
COLOR CLF(2),CLB(2): LOCATE 1,61: PRINT USING "##";SCORE(2);: PRINT " -";
COLOR 7,0
END SUB
SUB UNDO.MOVE STATIC
SHARED BOARD(),TOKEN$(),SCORE(),CLF(),CLB(),MOVE.NUM,PLAYERS,CUR.PLYR
SCORE(0)=0: SCORE(1)=0: SCORE(2)=0: MOVE.NUM=MOVE.NUM-(3-PLAYERS)
FOR Y=0 TO 7
FOR X=1 TO 8
A=Y*8+X: BOARD(A,0)=BOARD(A,MOVE.NUM)
A=BOARD(A,0): LOCATE Y*2+2,X*5-3
COLOR CLF(A),CLB(A): PRINT TOKEN$(A);: SCORE(A)=SCORE(A)+1
IF A THEN CALL MAKE.SOUND((6))
CALL WAIT.HERE((.05!))
NEXT
NEXT
COLOR CLF(1),CLB(1): LOCATE 1,46: PRINT USING "##";SCORE(1);: PRINT " -";
COLOR CLF(2),CLB(2): LOCATE 1,61: PRINT USING "##";SCORE(2);: PRINT " -";
COLOR 7,0: CUR.PLYR=BOARD(0,MOVE.NUM) XOR 3
END SUB
SUB WAIT.HERE(A!) STATIC
WHILE INKEY$<>"": WEND: B!=TIMER
WHILE INKEY$="" AND TIMER<(B!+A!): WEND
END SUB
SUB PRINT.MSG(MSG$,COL) STATIC
SHARED CLF(),CLB()
VIEW PRINT 25 TO 25: CLS: VIEW PRINT
COLOR CLF(COL),CLB(COL): LOCATE 25,1: PRINT MSG$;
END SUB
SUB DISPLAY.HELP STATIC
SHARED BOARD(),TOKEN$(),HELP.FLG: HELP.FLG=HELP.FLG XOR 1
FOR Y=0 TO 7
FOR X=1 TO 8
IF BOARD(Y*8+X,0)<0 THEN LOCATE Y*2+2,X*5-3:_
IF HELP.FLG THEN PRINT CHR$(222)+CHR$(28)+CHR$(28)+CHR$(221);_
ELSE PRINT " "+CHR$(28)+CHR$(28)+" ";
NEXT
NEXT
END SUB
SUB GET.MOVEMENT(DIR) STATIC
SHARED JS$,JS1,JS2: DIR=0: JSFL1=0: JSFL2=0
CALL MOUSE((1),(0),(0),(0))
WHILE DIR=0: A$=INKEY$
IF A$=CHR$(0)+CHR$(72) THEN DIR=1_
ELSE IF A$=CHR$(0)+CHR$(77) THEN DIR=3_
ELSE IF A$=CHR$(0)+CHR$(80) THEN DIR=5_
ELSE IF A$=CHR$(0)+CHR$(75) THEN DIR=7_
ELSE IF A$=CHR$(27) THEN DIR=9_
ELSE IF A$="H" OR A$="h" THEN DIR=10_
ELSE IF A$="U" OR A$="u" THEN DIR=11_
ELSE IF A$=" " OR A$=CHR$(13) THEN DIR=8_
ELSE IF A$<>"" AND DIR=0 THEN CALL MAKE.SOUND((1))
IF JS$="Y" THEN
A2=STICK(0): A2=STICK(0): A1=STICK(1)
IF JSFL1<>0 AND A1>JS1/2 AND A1<JS1+JS1/2 THEN DIR=JSFL1
IF JSFL2<>0 AND A2>JS2/2 AND A2<JS2+JS2/2 THEN DIR=JSFL2
IF JSFL1=0 THEN IF A1<JS1/2 THEN JSFL1=1 ELSE IF A1>JS1+JS1/2 THEN JSFL1=5
IF JSFL2=0 THEN IF A2<JS2/2 THEN JSFL2=7 ELSE IF A2>JS2+JS2/2 THEN JSFL2=3
IF STRIG(1) THEN WHILE STRIG(1): WEND: CALL WAIT.HERE((.1)): DIR=8
IF (INP(513) AND 32)=0 THEN WHILE (INP(513) AND 32)=0: WEND: CALL WAIT.HERE((.1)): DIR=10
END IF
M1=6: M2=1: CALL MOUSE(M1,M2,(0),(0)): IF (M1 AND 2)=0 AND M2>0 THEN DIR=10
M1=6: M2=0: CALL MOUSE(M1,M2,M3,M4)
IF (M1 AND 1)=0 AND M2>0 THEN
M3=M3/8: M4=M4/8
IF (M3 MOD 5)<>0 AND (M4 MOD 2)<>0 THEN_
M3=INT(M3/5)+1: M4=INT(M4/2): DIR=M3+M4*16+256
END IF
WEND: CALL MOUSE((2),(0),(0),(0))
END SUB
SUB MOUSE(M1,M2,M3,M4) STATIC
SHARED MOUSE.SEG,MOUSE.FLG,MOUSE
IF M1=-1 THEN
DEF SEG=0
MOUSE.SEG=PEEK(207)*256+PEEK(206): MOUSE=PEEK(205)*256+PEEK(204)+2
DEF SEG=MOUSE.SEG
IF PEEK(MOUSE-2)=207 OR PEEK(MOUSE-2)=0 THEN_
DEF SEG: MOUSE=0: MOUSE.SEG=0: MOUSE.FLG=0: GOTO MSRET
M1=0: CALL ABSOLUTE(M1,M2,M3,M4,MOUSE)
IF M1=0 THEN DEF SEG: MOUSE=0: MOUSE.SEG=0: MOUSE.FLG=0: GOTO MSRET
M1=7: M2=0: M3=8: M4=312: CALL ABSOLUTE(M1,M2,M3,M4,MOUSE)
M1=8: M2=0: M3=8: M4=120: CALL ABSOLUTE(M1,M2,M3,M4,MOUSE)
DEF SEG: MOUSE.FLG=1
ELSEIF MOUSE.FLG=1 AND (M1=0 OR M1=1 OR M1=2 OR M1=6 OR M1=10) THEN
DEF SEG=MOUSE.SEG: CALL ABSOLUTE(M1,M2,M3,M4,MOUSE): DEF SEG
END IF
MSRET:
END SUB
SUB CLEAR.LINE STATIC
LOCATE 24,1: PRINT SPACE$(79);: LOCATE 24,1
END SUB